<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>ccbft能力地图展示</title>
    <style type="text/css">
        html, body {
            margin: 0;
            height: 100%;
        }

        canvas {
            display: block;
        }

    </style>
</head>
<body onload="draw();">

</body>
<script src="resource/js/three.js"></script>
<script src="resource/js/GLTFLoader.js"></script>
<script src="resource/js/OrbitControls.js"></script>
<script src="resource/js/stats.min.js"></script>
<script src="resource/js/dat.gui.min.js"></script>
<script src="resource/js/jquery-3.5.1.min.js"></script>

<script>
    var arr1,arr2,arr3,arr4,arr5,arr6,arr7,arr8;
    // 能力地图json数据导入
    $(function() {
        $.ajax({
            type: "GET", 
            url: "data.json",
            //dataType: "json",
            //async: true,
            success: function(data) {
                console.log(data);
                // console.log(data.arr1);
                arr1 = data.arr1;   // 人工智能
                arr2 = data.arr2;   // 区块链
                arr3 = data.arr3;   // 云计算
                arr4 = data.arr4;   // 大数据
                arr5 = data.arr5;   // 分布式计算
                arr6 = data.arr6;   // 安全技术
                arr7 = data.arr7;   // 公共服务
                arr8 = data.arr8;   // 敏捷开发

                console.log(arr1);
                
                // console.log(data.arr1[3].text);
                
            }
        });
    });

    var renderer, camera, scene, gui, stats, ambientLight, directionalLight, control;
    var group1 = new THREE.Group();
    group1.name = "AI";

    var group2 = new THREE.Group();
    group2.name = "BlockChain";

    var group3 = new THREE.Group();
    group3.name = "CloudComputing";

    var group4 = new THREE.Group();
    group4.name = "BigData";

    var group5 = new THREE.Group();
    group5.name = "ICDP";

    var group6 = new THREE.Group();
    group6.name = "PublicServ";

    var group7 = new THREE.Group();
    group7.name = "Security";

    var group8 = new THREE.Group();
    group8.name = "DistributedComputing";

    var group3rd = new THREE.Group();
    group3rd.name = "ThirdTitle"


    function initRender() {
        renderer = new THREE.WebGLRenderer({
            antialias: true,
            // alpha: true
        });
        renderer.setSize(window.innerWidth, window.innerHeight);
        // renderer.setClearColor(0x000000, 0);
        // renderer.setClearAlpha(0.0);
        //告诉渲染器需要阴影效果
        // renderer.shadowMap.enabled = true;
        // renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 默认的是，没有设置的这个清晰 THREE.PCFShadowMap
        document.body.appendChild(renderer.domElement);
    }

    function initCamera() {
        camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 10, 1000);
        camera.position.set(-100, 90, 180);
        camera.lookAt(new THREE.Vector3(0, 100, 100));
    }

    function initScene() {
        scene = new THREE.Scene();

        // scene.background = new THREE.Color(0xf0f0f0)
        // let axesHelper = new THREE.AxesHelper(50)
        // scene.add(axesHelper)
    }

    function initGui() {
        //声明一个保存需求修改的相关数据的对象
        gui = {};

        var datGui = new dat.GUI();
        //将设置属性添加到gui当中，gui.add(对象，属性，最小值，最大值）
    }

    function initLight() {
        ambientLight = new THREE.AmbientLight("#111111");
        scene.add(ambientLight);

        directionalLight = new THREE.DirectionalLight("#ffffff");
        directionalLight.position.set(40, 60, 10);

        directionalLight.shadow.camera.near = 1; //产生阴影的最近距离
        directionalLight.shadow.camera.far = 400; //产生阴影的最远距离
        directionalLight.shadow.camera.left = -50; //产生阴影距离位置的最左边位置
        directionalLight.shadow.camera.right = 50; //最右边
        directionalLight.shadow.camera.top = 50; //最上边
        directionalLight.shadow.camera.bottom = -50; //最下面

        //这两个值决定生成阴影密度 默认512
        directionalLight.shadow.mapSize.height = 1024;
        directionalLight.shadow.mapSize.width = 1024;

        //告诉平行光需要开启阴影投射
        directionalLight.castShadow = true;

        scene.add(directionalLight);
    }

        // 状态显示，包括渲染帧率和显存占用情况
    function initStats() {
        stats = new Stats();
        document.body.appendChild(stats.dom);
    }

    // 轨道控制器，可以使相机围绕目标进行轨道运动
    function initControl() {
        control = new THREE.OrbitControls(camera, renderer.domElement);

    }

    function render() {

        control.update();

        renderer.render(scene, camera);
    }

    function onWindowResize() {

        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);

    }


    var time;
    function animate() {
        // //更新控制器
        // render();

        // //更新性能插件
        // stats.update();

        requestAnimationFrame(animate);
        var delta = clock.getDelta();
        // console.log("时间间隔", delta*1000);
        
        for(var i = 0; i < mixers.length; i++) {
            mixers[i].update(delta / 3);

        }

        stats.begin();
        render();
        stats.end();

    }


    function relativePosition(positionIndex) {
        var transferX = 0;
        var transferY = 0;
        var transferZ = 0;
        var group = new THREE.Group();

        // 一级能力文字相对于坐标(0,0,0)的位置
        switch (positionIndex) {
                case 0:
                    transferX = -100    // 一级标题的坐标
                    transferY = 45
                    transferZ = 70
                    px = -110   // 二级标题展示牌中第一块的坐标
                    py = 33
                    pz = 75
                    offsetA = 19    // 二级标题每一块在X轴上的偏移量（补偿）
                    offsetB = -5    // Y轴上的偏移量
                    group = group1
                    arr = arr1
                    SecondTitleMeshName = "textContainer_0_"
                    break;
                case 1:
                    transferX = -22
                    transferY = 45
                    transferZ = 70
                    px = -28
                    py = 33
                    pz = 75
                    offsetA = 19
                    offsetB = -5

                    group = group2
                    arr = arr2
                    SecondTitleMeshName = "textContainer_1_"
                    break;
                case 2:
                    transferX = 50
                    transferY = 40
                    transferZ = 70
                    px = 40
                    py = 33
                    pz = 75
                    offsetA = 19
                    offsetB = -5
                    group = group3
                    arr = arr3
                    SecondTitleMeshName = "textContainer_2_"
                    break;
                case 3:
                    transferX = 110
                    transferY = 40
                    transferZ = 70
                    px = 100
                    py = 33
                    pz = 80
                    offsetA = 19
                    offsetB = -5
                    group = group4
                    arr = arr4
                    SecondTitleMeshName = "textContainer_3_"
                    break;
                case 4:
                    transferX = 110
                    transferY = 50
                    transferZ = -50
                    px = 100
                    py = 43
                    pz = -35
                    offsetA = 19
                    offsetB = -5
                    group = group5
                    arr = arr5
                    SecondTitleMeshName = "textContainer_4_"
                    break;
                case 5:
                    transferX = 50
                    transferY = 50
                    transferZ = -50
                    px = 40
                    py = 43
                    pz = -35
                    offsetA = 19
                    offsetB = -5
                    group = group6
                    arr = arr6
                    SecondTitleMeshName = "textContainer_5_"
                    break;
                case 6:
                    transferX = -20
                    transferY = 50
                    transferZ = -50
                    px = -30
                    py = 43
                    pz = -45
                    offsetA = 19
                    offsetB = -5
                    group = group7
                    arr = arr7
                    SecondTitleMeshName = "textContainer_6_"
                    break;
                case 7:
                    transferX = -100
                    transferY = 50
                    transferZ = -50
                    px = -110
                    py = 43
                    pz = -45
                    offsetA = 19
                    offsetB = -5
                    group = group8
                    arr = arr8
                    SecondTitleMeshName = "textContainer_7_"
                    break;
        }
        return{
            transferX: transferX,
            transferY: transferY,
            transferZ: transferZ,
            px: px,
            py: py,
            pz: pz,
            offsetA: offsetA,
            offsetB: offsetB,
            group: group,
            arr: arr,
            SecondTitleMeshName: SecondTitleMeshName
        }
        
    }




    // 使用BoxGeometry和TextGeometry，通过坐标偏移创建二级能力展示牌
    function createTitle(itemName, position2, group, positionIndex,index) {
        
        // 创建展示牌
        var boxgeo = new THREE.BoxGeometry(18,4,0.1);
        var cubeMaterial = new THREE.MeshBasicMaterial({
            color: 0xFFFFFF
        });
        var cube = new THREE.Mesh(boxgeo, cubeMaterial);
        cube.name = "textContainer_"+positionIndex+"_"+index;
        // console.log(cube.name);
        
        group.add(cube);
        cube.position.x = position2.px;
        cube.position.y = position2.py;
        cube.position.z = position2.pz;

        // 创建文字
        var text = new THREE.FontLoader().load('resource/fonts/Microsoft YaHei_Regular.json', function(text) {
            var gem = new THREE.TextGeometry(itemName, {
                size: 1.5, //字号大小，一般为大写字母的高度
                height: 1, //文字的厚度
                weight: 'normal', //值为'normal'或'bold'，表示是否加粗
                font: text, //字体，默认是'helvetiker'，需对应引用的字体文件
                style: 'normal', //值为'normal'或'italics'，表示是否斜体
                bevelThickness: 1, //倒角厚度
                bevelSize: 1, //倒角宽度
                curveSegments: 10,//弧线分段数，使得文字的曲线更加光滑
                bevelEnabled: false, //布尔值，是否使用倒角，意为在边缘处斜切
            });
            gem.center();
            var mat = new THREE.MeshBasicMaterial({
                color: 'rgb(28,107,212)',
                // specular: 0x009900,
                // shininess: 10,
                // shading: THREE.FlatShading
            });
            var textObj = new THREE.Mesh(gem, mat);
            textObj.position.x = position2.px;
            textObj.position.y = position2.py;
            textObj.position.z = position2.pz;

            // textobj.rotation.x = 0;
            // textObj.rotation.y = Math.PI * 2;
     
            textObj.castShadow = true;
            textObj.name = "text_"+positionIndex+"_"+index;
            
            
            group.add(textObj);
            // console.log(group2);
            
            // new TWEEN.Tween(textObj.rotation).to({y: Math.PI * 2}, 2000).repeat(Infinity).yoyo(true).start();
        });
        // scene.add(group);
        // console.log(group2);

    }



    function init2ndTitle(items, positionIndex) {

        var px = relativePosition(positionIndex).px;
        var py = relativePosition(positionIndex).py;
        var pz = relativePosition(positionIndex).pz;
        var offsetA = relativePosition(positionIndex).offsetA;
        var offsetB = relativePosition(positionIndex).offsetB;
        var group = relativePosition(positionIndex).group;


        for (let index = 0; index < items.length; index++) {

            const item = items[index];
            if (index % 2 == 0) {
                createTitle(item.text,{
                    px: px,
                    py: py,
                    pz: pz,
                },group,positionIndex,index);
                // px += offsetA;
            } else {
                createTitle(item.text,{
                    px: px+offsetA,
                    py: py,
                    pz: pz,
                },group,positionIndex,index);
                py += offsetB;
            }
            scene.add(group);      
            
        }        
    }

    window.addEventListener("click",onMouseClick,false);
    
    var mouseVector = new THREE.Vector2();
    var raycaster = new THREE.Raycaster();
    function onMouseClick(event) {

        event.preventDefault();                
        x = (event.clientX / window.innerWidth) * 2 - 1;
        y = -(event.clientY / window.innerHeight) * 2 + 1;
        mouseVector.set(x, y);

		raycaster.setFromCamera(mouseVector, camera);

        // for (let i=0;i<8;i++) {
        //     present2ndTitle(i);
        // }


        for (let i=0;i<8;i++) {

            present2ndTitle(i);
            traverse2(i);
            
        }
        
        traverse3(group3rd);

    }

    // 通过点击一级标题创建二级能力展示牌
    function present2ndTitle(positionIndex) {

        var intersects = raycaster.intersectObject(scene.getObjectByName("title"+positionIndex)); 
        // console.log(scene.getObjectByName("title"+i));
        
                    
        if (intersects.length > 0) {
            // arr = "arr"+(i+1);
            // console.log(arr);
            arr = relativePosition(positionIndex).arr
            console.log(arr);
            
            init2ndTitle(arr,positionIndex);
            return;
            

        }
    }

    // 遍历增加3级能力展示牌
    function traverse2(positionIndex) {
        name = relativePosition(positionIndex).SecondTitleMeshName;
        group = relativePosition(positionIndex).group;
        for (let i=0;i<group.children.length;i++) {
            
            if (group.children[i].name === name+i) {
                
                var intersects = raycaster.intersectObject(group.children[i]);
                
                if (intersects.length > 0) {
                    arr = relativePosition(positionIndex).arr;
                    init3rdTitle(arr,positionIndex,i);
                    
                    return;
                    
                }
                
            }            
            
        }
    }
    
    // 遍历删除3级能力展示牌
    function traverse3(group) {
        for (let i=0;i<group.children.length;i++) {         
            if (group.children[i].name === "deleteBtn") {      
                var intersects = raycaster.intersectObject(group.children[i]);   
                if (intersects.length > 0) {
                    
                    // 删除一个object，需要注意删除一个object时，如果从第一个开始i[0]，后续的i[1] i[2]会向前平移至空缺位置
                    for (i=group3rd.children.length-1;i>=0;i--) {
                        obj = group3rd.children[i];
                        obj.geometry.dispose();
                        obj.material.dispose();
                        group3rd.remove(obj);
                    }
                    scene.remove(group3rd);
       
                }
            }
        }
    }

  
    // 创建三级能力展示牌
    function create3rdTitle(itemName, position2, group) {

        // 创建展示牌
        var boxgeo = new THREE.BoxGeometry(33,9,0.1);
        var cubeMaterial = new THREE.MeshBasicMaterial({
            color: 0xf0f0f0
        });
        var cube = new THREE.Mesh(boxgeo, cubeMaterial);
        // scene.add(cube);
        group.add(cube);
        cube.position.x = position2.px;
        cube.position.y = position2.py;
        cube.position.z = position2.pz;

        // 创建文字
        var text = new THREE.FontLoader().load('resource/fonts/Microsoft YaHei_Regular.json', function(text) {
            var gem = new THREE.TextGeometry(itemName, {
                size: 2, //字号大小，一般为大写字母的高度
                height: 1, //文字的厚度
                weight: 'normal', //值为'normal'或'bold'，表示是否加粗
                font: text, //字体，默认是'helvetiker'，需对应引用的字体文件
                style: 'normal', //值为'normal'或'italics'，表示是否斜体
                bevelThickness: 1, //倒角厚度
                bevelSize: 1, //倒角宽度
                curveSegments: 10,//弧线分段数，使得文字的曲线更加光滑
                bevelEnabled: false, //布尔值，是否使用倒角，意为在边缘处斜切
            });
            gem.center();
            var mat = new THREE.MeshBasicMaterial({
                color: 0x4B0082,
                // specular: 0x009900,
                // shininess: 10,
                // shading: THREE.FlatShading
            });
            var textObj = new THREE.Mesh(gem, mat);
            textObj.position.x = position2.px;
            textObj.position.y = position2.py;
            textObj.position.z = position2.pz;

            // textobj.rotation.x = 0;
            // textObj.rotation.y = Math.PI * 2;
     
            textObj.castShadow = true;
            // scene.add(textObj);
            group.add(textObj);
            // new TWEEN.Tween(textObj.rotation).to({y: Math.PI * 2}, 2000).repeat(Infinity).yoyo(true).start();
        });
        
    }

    function init3rdTitle(items, positionIndex, num) {

        
        var px = -25;
        var py = 60;
        var pz = 86;
        var offsetC = relativePosition(positionIndex).offsetC;

        var group = new THREE.Group();
        group = group3rd;
        // console.log(items);

        // 创建删除按钮
        var boxdel = new THREE.BoxGeometry(4,4,0.1);
        var texture = new THREE.TextureLoader().load("resource/img/deleteIcon.png");
        var boxdelMat = new THREE.MeshBasicMaterial({
            color:0xfFFFFF,  
            map:texture
        });
        var cubedel = new THREE.Mesh(boxdel,boxdelMat);
        cubedel.position.x = 52.5;
        cubedel.position.y = 68;
        cubedel.position.z = 86;
        cubedel.name = "deleteBtn";
        
        group.add(cubedel);
        

        // 创建背景板
        var boxbg = new THREE.BoxGeometry(110,70,0.1);
        var boxbgMat = new THREE.MeshBasicMaterial({color:0xffffff});
        var cubebg = new THREE.Mesh(boxbg,boxbgMat);
        cubebg.name = "backgroudPlane";
        cubebg.position.x = 0;
        cubebg.position.y = 35;
        cubebg.position.z = 85;
        group.add(cubebg);

        const item = items[num];
        
        for (let i = 0; i < item.text2.length; i++) {

            if (i % 2 == 0) {
                create3rdTitle(item.text2[i],{
                    px: px,
                    py: py,
                    pz: pz,
                },group);
            } else {
                create3rdTitle(item.text2[i],{
                    px: px + 50,
                    py: py,
                    pz: pz,
                },group);
                py -= 10;
            }

            // py += offsetC;

        }
        scene.add(group);
          
    }
    

    var mixers = [];
    var clock = new THREE.Clock();
    function initModel() {

        // var texture = new THREE.TextureLoader().load("resource/img/checkerboard.jpg");
        var texture2 = new THREE.TextureLoader().load("resource/img/modelTexture.png");

        // var planeGeometry = new THREE.PlaneGeometry(1000, 1000);
        // var planeMaterial = new THREE.MeshPhongMaterial({color: 0x000000, side: THREE.DoubleSide, map: texture, transparent: false, opacity:0.3});

        // var plane = new THREE.Mesh(planeGeometry, planeMaterial);
        // plane.rotation.x = -0.5 * Math.PI;
        // plane.position.y = -.1;
        // plane.receiveShadow = true; //可以接收阴影
        // scene.add(plane);

        
        // // FLOOR
        // var floorTexture = new THREE.ImageUtils.loadTexture( 'resource/img/checkerboard.jpg' );
        // // floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping; 
        // // floorTexture.repeat.set( 10, 10 );
        // var floorMaterial = new THREE.MeshBasicMaterial( { map: floorTexture, side:THREE.DoubleSide } );
        // var floorGeometry = new THREE.PlaneGeometry(1000, 1000, 10, 10);
        
       
        // var floor = new THREE.Mesh(floorGeometry, floorMaterial);
        // // floor.position.y = -40.5;
        // // floor.rotation.x = Math.PI / 2;
        // floor.rotation.x = -0.5 * Math.PI;
        // floor.position.y = -.1;
        // scene.add(floor);
        
        // FLOOR
        createFloor(1024, 800, 0xfff0ff);
        // create sky 
        // createSkyBox(5000, 5000, 5000);
        // create sky 
        var skyGeo = new THREE.SphereGeometry(500,60,40);
        var skyTexture = new THREE.TextureLoader().load("resource/img/sky.jpg");
        var skyMaterial = new THREE.MeshPhongMaterial({map:skyTexture});
        var sky = new THREE.Mesh(skyGeo, skyMaterial);
        sky.material.side = THREE.BackSide;
        scene.add(sky);
        
        //创建gltf加载器
        var loader = new THREE.GLTFLoader();
        var group = new THREE.Group();
        //创建底板
        function createFloor(width, height,color) {
            // FLOOR
            var floorGeometry = new THREE.PlaneGeometry(width, height);
            var floorMaterial = new THREE.MeshBasicMaterial( { color: color, opacity: 0.4, transparent: true,side: THREE.DoubleSide } );
            var floor = new THREE.Mesh(floorGeometry, floorMaterial);
            //floor.position.x = 0;
            //floor.position.y = 0;
            //floor.position.z = 0;
            
            floor.rotation.x = Math.PI / 2;

            scene.add(floor);
            // targetList.push(floor);
            
            return floor;
          }

        //创建天空盒
        function createSkyBox(width, height,size) {
            var imagePrefix = "resource/img/dawnmountain-";
            var directions  = ["xpos", "xneg", "ypos", "yneg", "zpos", "zneg"];
            var imageSuffix = ".png";
            var skyGeometry = new THREE.CubeGeometry( width, height, size );	
            
            var materialArray = [];
            for (var i = 0; i < 6; i++)
                materialArray.push( new THREE.MeshBasicMaterial({
                    map: THREE.ImageUtils.loadTexture( imagePrefix + directions[i] + imageSuffix ),
                    side: THREE.BackSide
                }));
            var skyMaterial = new THREE.MeshFaceMaterial( materialArray );
            var skyBox = new THREE.Mesh( skyGeometry, skyMaterial );
            scene.add( skyBox );
            return skyBox;
          }

        // 创建人工智能模块
        loader.load('resource/model/model1.gltf', function (gltf) {
            gltf.scene.scale.set(.1,.1,.1);
            scene.add(gltf.scene);
            gltf.scene.traverse(function (child) {
                if (child instanceof THREE.Mesh) {

                    // apply texture
                    child.material.alphaTest = 0.5;
                    child.material.map = texture2;
                    child.material.needsUpdate = true;
                }
                });

                gltf.scene.position.x = -100;
                gltf.scene.position.y = 20;
                gltf.scene.position.z = 65;
            // 调用动画
                var mixer = new THREE.AnimationMixer(gltf.scene.children[0]);             
                mixer.clipAction(gltf.animations[0]).setDuration(1).play();
                mixers.push(mixer);
                createText("人工智能",0);
        });


        // 区块链模块
        loader.load('resource/model/model2.gltf', function (gltf) {
            gltf.scene.scale.set(.1,.1,.1);
            scene.add(gltf.scene);
            gltf.scene.traverse(function (child) {
                if (child instanceof THREE.Mesh) {

                    // apply texture
                    child.material.alphaTest = 0.5;
                    child.material.map = texture2;
                    child.material.needsUpdate = true;
                }
                });

                gltf.scene.position.x = -20;
                gltf.scene.position.y = 20;
                gltf.scene.position.z = 65;
            // 调用动画
                var mixer = new THREE.AnimationMixer(gltf.scene.children[0]);             
                mixer.clipAction(gltf.animations[0]).setDuration(1).play();
                mixers.push(mixer);
                createText("区块链",1);
        });

        // 云技术模块
        loader.load('resource/model/model3.gltf', function (gltf) {
            gltf.scene.scale.set(.1,.1,.1);
            scene.add(gltf.scene);
            gltf.scene.traverse(function (child) {
                if (child instanceof THREE.Mesh) {

                    // apply texture
                    child.material.alphaTest = 0.5;
                    child.material.map = texture2;
                    child.material.needsUpdate = true;
                }
                });

                gltf.scene.position.x = 50;
                gltf.scene.position.y = 20;
                gltf.scene.position.z = 65;
            // 调用动画
                var mixer = new THREE.AnimationMixer(gltf.scene.children[0]);             
                mixer.clipAction(gltf.animations[0]).setDuration(1).play();
                mixers.push(mixer);
                createText("云计算",2);
        });


        // 大数据模块
        loader.load('resource/model/model4.gltf', function (gltf) {
            gltf.scene.scale.set(.1,.1,.1);
            scene.add(gltf.scene);
            gltf.scene.traverse(function (child) {
                if (child instanceof THREE.Mesh) {

                    // apply texture
                    child.material.alphaTest = 0.5;
                    child.material.map = texture2;
                    child.material.needsUpdate = true;
                }
                });

                gltf.scene.position.x = 110;
                gltf.scene.position.y = 20;
                gltf.scene.position.z = 65;
            // 调用动画
                var mixer = new THREE.AnimationMixer(gltf.scene.children[0]);             
                mixer.clipAction(gltf.animations[0]).setDuration(1).play();
                mixers.push(mixer);
                createText("大数据",3);
        });
        
        // 分布式计算模块
        loader.load('resource/model/model5.gltf', function (gltf) {
            gltf.scene.scale.set(.1,.1,.1);
            scene.add(gltf.scene);
            gltf.scene.traverse(function (child) {
                if (child instanceof THREE.Mesh) {

                    // apply texture
                    child.material.alphaTest = 0.5;
                    child.material.map = texture2;
                    child.material.needsUpdate = true;
                }
                });

                gltf.scene.position.x = 110;
                gltf.scene.position.y = 20;
                gltf.scene.position.z = -50;
            // 调用动画
                var mixer = new THREE.AnimationMixer(gltf.scene.children[0]);             
                mixer.clipAction(gltf.animations[0]).setDuration(1).play();
                mixers.push(mixer);
                createText("分布式计算",4);
        });
        

        // 安全技术模块
        loader.load('resource/model/model6.gltf', function (gltf) {
            gltf.scene.scale.set(.1,.1,.1);
            scene.add(gltf.scene);
            gltf.scene.traverse(function (child) {
                if (child instanceof THREE.Mesh) {

                    // apply texture
                    child.material.alphaTest = 0.5;
                    child.material.map = texture2;
                    child.material.needsUpdate = true;
                }
                });

                gltf.scene.position.x = 50;
                gltf.scene.position.y = 20;
                gltf.scene.position.z = -50;
            // 调用动画
                var mixer = new THREE.AnimationMixer(gltf.scene.children[0]);             
                mixer.clipAction(gltf.animations[0]).setDuration(1).play();
                mixers.push(mixer);
                createText("安全技术",5);
        });
        
        
        // 公共服务模块
        loader.load('resource/model/model7.gltf', function (gltf) {
            gltf.scene.scale.set(.1,.1,.1);
            scene.add(gltf.scene);
            gltf.scene.traverse(function (child) {
                if (child instanceof THREE.Mesh) {

                    // apply texture
                    child.material.alphaTest = 0.5;
                    child.material.map = texture2;
                    child.material.needsUpdate = true;
                }
                });

                gltf.scene.position.x = -20;
                gltf.scene.position.y = 20;
                gltf.scene.position.z = -55;
            // 调用动画
                var mixer = new THREE.AnimationMixer(gltf.scene.children[0]);             
                mixer.clipAction(gltf.animations[0]).setDuration(1).play();
                mixers.push(mixer);
                createText("公共服务",6);
        });

        // 敏捷开发模块
        loader.load('resource/model/model8.gltf', function (gltf) {
            gltf.scene.scale.set(.1,.1,.1);
            scene.add(gltf.scene);
            gltf.scene.traverse(function (child) {
                if (child instanceof THREE.Mesh) {

                    // apply texture
                    child.material.alphaTest = 0.5;
                    child.material.map = texture2;
                    child.material.needsUpdate = true;
                }
                });

                gltf.scene.position.x = -100;
                gltf.scene.position.y = 5;
                gltf.scene.position.z = -55;
            // 调用动画
                var mixer = new THREE.AnimationMixer(gltf.scene.children[0]);             
                mixer.clipAction(gltf.animations[0]).setDuration(1).play();
                mixers.push(mixer);
                createText("敏捷开发",7);
        });

    }


    // // 使用sprite绘制展示牌，文字锯齿化严重，此方案不采纳
    // function createText(groupname, positionIndex) {

    //     //使用画布动态生成文字
    //     let canvas = document.createElement("canvas");
    //     let ctx = canvas.getContext("2d");
    //     ctx.fillStyle = "#ffff00";
    //     ctx.font = "normal 22px Georgia";
    //     ctx.lineWidth = 4;
    //     ctx.fillText(groupname, 0, 50);
    //     let texture = new THREE.Texture(canvas);
    //     texture.needsUpdate = true;
    //     //使用sprite显示文字
    //     let material = new THREE.SpriteMaterial({map:texture, transparent:true});
    //     let textObj = new THREE.Sprite(material);
    //     textObj.scale.set(64, 64, 10);
            
    //     textObj.position.x = relativePosition(positionIndex).transferX;
    //     textObj.position.y = relativePosition(positionIndex).transferY;
    //     textObj.position.z = relativePosition(positionIndex).transferZ;

 
    //     scene.add(textObj);
    // }



    // 绘制一级能力标题文字
    function createText(title, positionIndex) {
        // var group = new THREE.Group();
        // group = relativePosition(positionIndex).group;
        var text = new THREE.FontLoader().load('resource/fonts/Microsoft YaHei_Regular.json', function(text) {
            var gem = new THREE.TextGeometry(title, {
                size: 4, //字号大小，一般为大写字母的高度
                height: 1, //文字的厚度
                weight: 'normal', //值为'normal'或'bold'，表示是否加粗
                font: text, //字体，默认是'helvetiker'，需对应引用的字体文件
                style: 'normal', //值为'normal'或'italics'，表示是否斜体
                bevelThickness: 1, //倒角厚度
                bevelSize: 1, //倒角宽度
                curveSegments: 10,//弧线分段数，使得文字的曲线更加光滑
                bevelEnabled: false, //布尔值，是否使用倒角，意为在边缘处斜切
            });
            gem.center();
            var mat = new THREE.MeshNormalMaterial({
                // color: 'rgb(28,107,212)',
                // specular: 0x009900,
                // shininess: 10,
                // shading: THREE.FlatShading
            });
            var textObj = new THREE.Mesh(gem, mat);
            textObj.transferX = -100;
            textObj.position.x = relativePosition(positionIndex).transferX;
            textObj.position.y = relativePosition(positionIndex).transferY;
            textObj.position.z = relativePosition(positionIndex).transferZ;

            // textobj.rotation.x = 0;
            // textObj.rotation.y = Math.PI * 2;
            textObj.name = "title"+positionIndex;
            textObj.castShadow = true;
            scene.add(textObj);
            // group.add(textObj);
            // scene.add(group);
        });
    }



    function draw() {
        initGui();
        initRender();
        initScene();
        initCamera();
        initLight();
        initModel();
        initStats();
        initControl();
        animate();
        window.onresize = onWindowResize;
    }
</script>
</html>